﻿using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Should;

namespace NGeo.Yahoo.PlaceFinder
{
    [TestClass]
    public class PlaceFinderClientTests
    {
        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_ShouldBePublic()
        {
            using (var client = new PlaceFinderClient())
            {
                client.ShouldNotBeNull();
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_ReverseGeocode_ShouldReturn1Result_ForLehighLatitudeAndLongitude()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new ReverseRequest
                {
                    Latitude = 40.60326613801468,
                    Longitude = -75.37771224975586,
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                };

                var results = client.ReverseGeocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
                results.Items[0].RadiusInMeters.ShouldBeInRange(0, 5000);
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_ReverseGeocode_ShouldReturnNull_WhenLatitudeAndLongitudeAreNotSpecified()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new ReverseRequest
                {
                    Latitude = 4000.60326613801468,
                    Longitude = -7500.37771224975586,
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                };

                var results = client.ReverseGeocode(request);
                results.ShouldBeNull();
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByLocation_WhenLocationIsNotNullOrWhiteSpace()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    Location = "Edinburgh Napier University",
                    Name = "Edinburgh Napier University",
                    WoeId = 23702111,
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                        RequestFlag.Php,
                        RequestFlag.BoundingBox,
                        RequestFlag.StreetDetail,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
                results.Items[0].RadiusInMeters.ShouldBeInRange(0, 5000);
                results.Items[0].BoundingBox.ShouldNotBeNull();
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByName_WhenNameIsNotNullOrWhiteSpace()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    Name = "Future University of Egypt",
                    WoeId = 23702111,
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                        RequestFlag.BoundingBox,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldBeNull();
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByWoeId_WhenWoeIdIsNotNull()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    WoeId = 23702111,
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                        RequestFlag.BoundingBox,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByAddressLines_WhenNoAddressLinesAreNotNullOrWhitespace()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    Line1 = "116 E 55th Street",
                    Line2 = "New York, NY",
                    Line3 = "10022",
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByAddressLines_WhenAddressLine1IsNotNullOrWhitespace()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    Line1 = "116 E 55th Street New York, NY 10022",
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByAddressLines_WhenAddressLine2IsNotNullOrWhitespace()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    Line2 = "116 E 55th Street New York, NY 10022",
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByAddressLines_WhenAddressLine3IsNotNullOrWhitespace()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    Line3 = "116 E 55th Street New York, NY 10022",
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
            }
        }

        [TestMethod]
        public void Yahoo_PlaceFinder_PlaceFinderClient_Geocode_ShouldQueryByOther_WhenOtherRequestOptionsAreNotPresent()
        {
            using (var client = new PlaceFinderClient())
            {
                var request = new Request
                {
                    HouseNumber = "1600",
                    StreetName = "Pennsylvania Avenue",
                    Level0 = "US",
                    Level1 = "DC",
                    Unit = null,
                    UnitType = null,
                    CrossStreet = null,
                    Postal = null,
                    Level4 = null,
                    Level3 = null,
                    Level2 = null,
                    AppId = null,
                    Locale = "en_US",
                    Flags = new HashSet<RequestFlag>
                    {
                        RequestFlag.Global,
                    },
                    GFlags = new HashSet<RequestGFlag>
                    {
                        RequestGFlag.LimitToLocaleCountry,
                    },
                };

                var results = client.Geocode(request);
                results.ShouldNotBeNull();
                results.Items.ShouldNotBeNull();
                results.Items.Count.ShouldEqual(1);
            }
        }

    }
}
